package com.ccteam.fluidmusic.ui.artist

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.recyclerview.widget.ConcatAdapter
import com.ccteam.fluidmusic.NavArtistDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentArtistListBinding
import com.ccteam.fluidmusic.utils.TransitionUtils
import com.ccteam.fluidmusic.view.adapters.ArtistListItemClickCallback
import com.ccteam.fluidmusic.view.adapters.ArtistListPagingAdapter
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.adapters.toolbar.ToolbarTitleAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.widget.AnimToolbarScrollListener
import com.ccteam.shared.result.artist.ArtistListItem
import com.ccteam.shared.result.title.ToolbarTitleItem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class ArtistListFragment : Fragment() {

    private var _binding : FragmentArtistListBinding? = null
    private val binding get() = _binding!!

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    private val artistListViewModel: ArtistListViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        exitTransition = TransitionUtils.exitScale
        reenterTransition = TransitionUtils.enterScale
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentArtistListBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        postponeEnterTransition()
        view.doOnPreDraw {
            startPostponedEnterTransition()
        }

        val titleAdapter = ToolbarTitleAdapter()

        lightBounceEdgeEffectFactory.applyBounceView(binding.rvArtistList,this)
        binding.rvArtistList.edgeEffectFactory = lightBounceEdgeEffectFactory

        binding.toolbarArtistList.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        titleAdapter.submitList(mutableListOf(ToolbarTitleItem(getString(R.string.online_music_artist_type))))

        val dataAdapter = ArtistListPagingAdapter(artistListItemClickCallback)

        binding.rvArtistList.adapter = ConcatAdapter(titleAdapter,dataAdapter.withLoadStateFooter(
            CustomLoadStateAdapter(dataAdapter){
                dataAdapter.retry()
            }
        ))

        binding.rvArtistList.addOnScrollListener(AnimToolbarScrollListener(binding.toolbarTitle))

        viewLifecycleOwner.lifecycleScope.launch {
            artistListViewModel.artistListFlow.collectLatest { artists ->
                dataAdapter.submitData(artists)
            }
        }

        viewLifecycleOwner.lifecycleScope.launch {
            // 当分页状态变化时进行对应设置，这里单独监听 refresh 状态，显示的是全局加载进度条和错误提示。
            // 如果是分页滑动过程中的错误，在列表的Footer处已经配置
            dataAdapter.loadStateFlow.collectLatest { state ->
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)

                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && dataAdapter.itemCount < 1)
            }
        }

        binding.statusView.setRetryClickListener {
            dataAdapter.refresh()
        }

    }

    private val artistListItemClickCallback = object: ArtistListItemClickCallback {

        override fun artistItemClicked(view: View,item: ArtistListItem) {
            val musicListDetailTransitionName = getString(R.string.artist_detail_transition_name)
            val extra = FragmentNavigatorExtras(view to musicListDetailTransitionName)

            findNavController().navigate(NavArtistDirections.actionGlobalArtistDetailFragment(
                item.artistId
            ),extra)
        }

    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.rvArtistList.clearOnScrollListeners()
        _binding = null
    }
}